package com.ilovepostcard.controller.server;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.DefaultHttpClient;

import android.util.Log;

import com.ilovepostcard.utils.Constants;

public class PostcardServer implements IServer {
//    private static final String LOGTAG = "PostcardServer";

    private static final String URL_BASE = "http://gateway.ilovepostcard.com/action2.aspx?";

//    private static final int HTTP_TIME_OUT = 30 * 1000;

    @Override
    public PostcardResult login(String uname, String pwd) {
        PostcardRequest request = PostcardRequest.createRequestForUserLogin(uname, pwd);
        return doGet(request);
    }

    @Override
    public PostcardResult register(String uname, String pwd, String nickname) {
        PostcardRequest request = PostcardRequest.createRequestForUserRegister(uname, pwd, nickname);
        return doGet(request);
    }

    @Override
    public PostcardResult userLoginFromOpen(String uname, String nickname,
            int type) {
        PostcardRequest request = PostcardRequest.createRequestForUserLoginFromOpen(uname, nickname, type);
        return doGet(request);
    }

    @Override
    public PostcardResult getUserInfo(String uname, long uid) {
        PostcardRequest request = PostcardRequest.createRequestForGetUserInfo(uname, uid);
        return doGet(request);
    }
    
    

    @Override
    public PostcardResult getRecommendPostcard(long uid, int pi, int pc) {
        PostcardRequest request = PostcardRequest.createRequestForGetRecommendPostcard(uid, pi, pc);
        return doGet(request);
    }

    @Override
    public PostcardResult getFriendPostcard(long uid, int pi, int pc) {
        PostcardRequest request = PostcardRequest.createRequestForGetFriendPostcard(uid, pi, pc);
        return doGet(request);
    }

    @Override
    public PostcardResult getMyPostcard(long uid, int pi, int pc) {
        PostcardRequest request = PostcardRequest.createRequestForGetMyPostcard(uid, pi, pc);
        return doGet(request);
    }
    
    @Override
    public PostcardResult searchPostcard(String keyword, int pi, int pc) {
        PostcardRequest request = PostcardRequest.createRequestForSearchPostcard(keyword, pi, pc);
        return doGet(request);
    }

    @Override
    public PostcardResult updateUserInfo(long uid, int sex, String birthday, String province, String city,
            String introduction, String nickname) {
        PostcardRequest request = PostcardRequest.createRequestForUpdateUserInfo(uid, sex, birthday, province, city, introduction, nickname);
        return doGet(request);
    }

    @Override
    public PostcardResult getUploadSKey() {
        PostcardRequest request = PostcardRequest.createRequestForGetUploadSKey();
        return doGet(request);
    }

    @Override
    public PostcardResult uploadFile(int type, String fileName, String skey,
            long uid, int x, int y, int w, int h, int r, File source) {
        PostcardRequest request = PostcardRequest.createRequestForUploadFile(type, fileName, skey, uid, x, y, w, h, r);
        return doPost(request, source);
    }
    
    @Override
    public PostcardResult canModifyNickname(long uid) {
        PostcardRequest request = PostcardRequest.createRequestForCanModifyNickname(uid);
        return doGet(request);
    }

    @Override
    public PostcardResult listCity() {
        PostcardRequest request = PostcardRequest.createRequestForListCity();
        return doGet(request);
    }
    
    @Override
    public PostcardResult createPostcard(long uid, String location,
            String tofriendswords, String story, boolean isshowwords,
            double latitude, double longitude, String skey, int viewPermission,
            int locationPermission, String tags) {
        PostcardRequest request = PostcardRequest
                .createRequestForCreatePostcard(uid, location, tofriendswords,
                        story, isshowwords, latitude, longitude, skey,
                        viewPermission, locationPermission, tags);
        return doGet(request);
    }
    
    @Override
    public PostcardResult deletePostcard(long pid, long uid) {
        PostcardRequest request = PostcardRequest.createRequestForDeletePostcard(pid, uid);
        return doGet(request);
    }
    
    @Override
    public PostcardResult postProposal(long uid, String body) {
        PostcardRequest request = PostcardRequest.createRequestForPostProposal(uid, body);
        return doGet(request);
    }
    
    @Override
    public PostcardResult checkNew(String ver, String channel) {
        PostcardRequest request = PostcardRequest.createRequestForCheckNew(ver, channel);
        return doGet(request);
    }
    
    @Override
    public PostcardResult attention(long uidMy, long uidOther, int type) {
        PostcardRequest request = PostcardRequest.createRequestForAttention(uidMy, uidOther, type);
        return doGet(request);
    }
    
    @Override
    public PostcardResult checkAttention(long uidMy, long uidOther) {
        PostcardRequest request = PostcardRequest.createRequestForCheckAttention(uidMy, uidOther);
        return doGet(request);
    }
    
    @Override
    public PostcardResult getAttentionList(long uid, int type, int pi, int pc) {
        PostcardRequest request = PostcardRequest.createRequestForGetAttentionList(uid, type, pi, pc);
        return doGet(request);
    }
    
    @Override
    public PostcardResult getPostcardInfo(long pid) {
        PostcardRequest request = PostcardRequest.createRequestForGetPostcardInfo(pid);
        return doGet(request);
    }

    @Override
    public PostcardResult getUserActiveTime(long uid) {
        PostcardRequest request = PostcardRequest.createRequestForGetUserActiveTime(uid);
        return doGet(request);
    }
    
    @Override
    public PostcardResult likePostcard(long uid, long pid) {
        PostcardRequest request = PostcardRequest.createRequestForLikePostcard(uid, pid);
        return doGet(request);
    }
    
    @Override
    public PostcardResult newPostcardComment(long uid, long pid, String body) {
        PostcardRequest request = PostcardRequest.createRequestForNewPostcardComment(uid, pid, body);
        return doGet(request);
    }

    @Override
    public PostcardResult getPostcardComments(long pid, int pi, int pc) {
        PostcardRequest request = PostcardRequest.createRequestForGetPostcardComments(pid, pi, pc);
        return doGet(request);
    }

    @Override
    public PostcardResult searchUser(String k, int pi, int pc) {
        PostcardRequest request = PostcardRequest.createRequestForSearchUser(k, pi, pc);
        return doGet(request);
    }

    @Override
    public PostcardResult getNewMessageCount(long uid) {
        PostcardRequest request = PostcardRequest.createRequestForGetNewMessageCount(uid);
        return doGet(request);
    }

    @Override
    public PostcardResult deleteMessage(long uid, long mid) {
        PostcardRequest request = PostcardRequest.createRequestForDeleteMessage(uid, mid);
        return doGet(request);
    }

    @Override
    public PostcardResult listMessage(long uid, int pi, int pc) {
        PostcardRequest request = PostcardRequest.createRequestForListMessage(uid, pi, pc);
        return doGet(request);
    }

    @Override
    public PostcardResult getUserHeadImg(long uid) {
        PostcardRequest request = PostcardRequest.createRequestForGetUserHeadImg(uid);
        return doGet(request);
    }

    @Override
    public PostcardResult listAddress(long uid, int pi, int pc) {
        PostcardRequest request = PostcardRequest.createRequestForListAddress(uid, pi, pc);
        return doGet(request);
    }

    @Override
    public PostcardResult newAddress(long uid, String name, String telephone,
            String province, String city, String address, String zipcode) {
        PostcardRequest request = PostcardRequest.createRequestForNewAddress(uid, name, telephone, province, city, address, zipcode);
        return doGet(request);
    }

    @Override
    public PostcardResult newOrder(String type, long uid, long[] pids,
            String sendword, long[] aids) {
        PostcardRequest request = PostcardRequest.createRequestForNewOrder(type, uid, pids, sendword, aids);
        return doGet(request);
    }

    @Override
    public PostcardResult listOrder(long uid, int pi, int pc) {
        PostcardRequest request = PostcardRequest.createRequestForListOrder(uid, pi, pc);
        return doGet(request);
    }

    @Override
    public PostcardResult getOrderInfo(long oid) {
        PostcardRequest request = PostcardRequest.createRequestForGetOrderInfo(oid);
        return doGet(request);
    }

    @Override
    public PostcardResult checkLike(long uid, long pid) {
        PostcardRequest request = PostcardRequest.createRequestForCheckLike(uid, pid);
        return doGet(request);
    }

    @Override
    public PostcardResult getShareTextConfig(int type, long uid, long pid) {
        PostcardRequest request = PostcardRequest.createRequestForGetShareTextConfig(type, uid, pid);
        return doGet(request);
    }

    @Override
    public PostcardResult getLastPostcardComment(long uid, long pid) {
        PostcardRequest request = PostcardRequest.createRequestForGetLastPostcardComment(uid, pid);
        return doGet(request);
    }

    @Override
    public PostcardResult GetBuycartUrl(long uid) {
        PostcardRequest request = PostcardRequest.createRequestForGetBuycartUrl(uid);
        return doGet(request);
    }

    private static PostcardResult doPost(PostcardRequest request, File source) {

        String url = URL_BASE + request.getRequestString();
        HttpPost httpPost = new HttpPost(url);
        HttpClient httpClient = new DefaultHttpClient();

        HttpResponse response = null;

        try {
            FileEntity entity = new FileEntity(source, "binary/octet-stream");

            // InputStreamEntity entity = new InputStreamEntity(source,
            // source.available());

            httpPost.setEntity(entity);

            response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == 200) {
                byte[] retval = null;
                HttpEntity responseEntity = response.getEntity();
                InputStream inStream = getUngzippedContent(responseEntity);
                byte[] buffer = new byte[1024 * 4];
                DataInputStream dis = new DataInputStream(inStream);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int length = 0;
                while ((length = dis.read(buffer)) != -1) {
                    baos.write(buffer, 0, length);
                }
                retval = baos.toByteArray();
                baos.close();
                dis.close();
                PostcardResult result = PostcardResult.parserResult(new String(
                        retval));
                return result;
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
    
    private static InputStream getUngzippedContent(HttpEntity entity)
            throws IOException {
        InputStream responseStream = entity.getContent();
        if (responseStream == null) {
            return responseStream;
        }
        Header header = entity.getContentEncoding();
        if (header == null) {
            return responseStream;
        }
        String contentEncoding = header.getValue();
        if (contentEncoding == null) {
            return responseStream;
        }
        if (contentEncoding.contains("gzip")) {
            responseStream = new GZIPInputStream(responseStream);
        }
        return responseStream;
    }

    private static PostcardResult doGet(PostcardRequest request) {
        String url = URL_BASE + request.getRequestString();
        String response = _httpGet(url);
        PostcardResult result = PostcardResult.parserResult(response);
        return result;
    }

//    private static String _httpGet(String url) {
//        BufferedReader br = null;
//        try {
//            URL myUrl = new URL(url);
//            HttpURLConnection connection = (HttpURLConnection) myUrl.openConnection();
//            connection.setRequestMethod("GET");
//            connection.setConnectTimeout(HTTP_TIME_OUT);
//            connection.connect();
//            int code = connection.getResponseCode();
//            StringBuilder buffer = new StringBuilder();
//            if (HttpURLConnection.HTTP_OK == code) {
//                br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
//                String line = null;
//                while ((line = br.readLine()) != null) {
//                    buffer.append(line);
//                }
//            }
//            return buffer.toString();
//        } catch (IOException e) {
//            Log.e(LOGTAG, "HTTP GET error", e);
//        } finally {
//            if (br != null) {
//                try {
//                    br.close();
//                } catch (Exception e) {
//
//                }
//            }
//        }
//        return null;
//    }
    
    private static String _httpGet(String url) {
        InputStream inStream = null;
        try {
          
            String url2 = url.replace(" ","%20");
            byte[] retval = null;
            HttpGet httpPost = new HttpGet(url2);
            HttpClient httpClient = new DefaultHttpClient();
            
            HttpResponse response = httpClient.execute(httpPost);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();
                inStream = getUngzippedContent(entity);
                byte[] buffer = new byte[1024 * 4];
                DataInputStream dis = new DataInputStream(inStream);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                int length = 0;
                while ((length = dis.read(buffer)) != -1) {
                    baos.write(buffer, 0, length);
                }
                retval = baos.toByteArray();
                baos.close();
                dis.close();
                return new String(retval, "utf-8");
            }else{
                Log.d(Constants.TAG,"response = " + response.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
        } finally {
            if (inStream != null)
                try {
                    inStream.close();
                } catch (Exception e2) {

                }
        }
        return null;
    }

}
